﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MapInfo.MiPro.Interop;
using System.Runtime.InteropServices;

namespace MapWindowDocking
{
    public partial class LegendControl : UserControl
    {
        // Sets the parent of a window.
        [DllImport("User32", CharSet = CharSet.Auto, ExactSpelling = true)]
        internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndParent);

        //Sets window attributes
        [DllImport("USER32.DLL")]
        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        //Gets window attributes
        [DllImport("USER32.DLL")]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        //assorted constants needed
        public static int GWL_STYLE = -16;
        public static int WS_CHILD = 0x40000000; //child window
        public static int WS_BORDER = 0x00800000; //window with border
        public static int WS_DLGFRAME = 0x00400000; //window with double border but no title
        public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar
        public static int WS_MAXIMIZE = 0x1000000;
        public static int WS_THICKFRAME = 0x40000;
        
        private readonly MapinfoWrapper mapinfo;
        
        public LegendControl(MapinfoWrapper mapinfoSession)
        {
            InitializeComponent();
            this.mapinfo = mapinfoSession;
        }

        private void reparentLegend_Click(object sender, EventArgs e)
        {
            //TODO: Need to implement backgroud search for legend control.
            string noofwindows = this.mapinfo.Eval("NumAllWindows()");
            int number = Convert.ToInt32(noofwindows);
            for (int i = 0; i < number; i--)
            {
                string windowId = this.mapinfo.Eval("WindowID(" + i + ")");
                string windowType = this.mapinfo.Eval("WindowInfo(" + i + ",3)");

                // We have a legand.
                if (windowType == "27")
                {
                    string ownerwindowid = this.mapinfo.Eval("WindowInfo(" + i + ",10)");
                    // Does this window own this legend.
                    if (ownerwindowid == this.AssociatedWindow.ID.ToString())
                    {
                        //Get the windows handle
                        string handle = this.mapinfo.Eval("WindowInfo(" + windowId + ",12)");
                        this.LegandHandle = new IntPtr(Convert.ToInt32(handle)); ;
                        this.LegendId = Convert.ToInt32(windowId);

                        //Set the parent of legend window to a picture box on the form.
                        SetParent(this.LegandHandle, this.legandArea.Handle);
                        //Get current window style of MapInfo window
                        int style = GetWindowLong(this.LegandHandle, GWL_STYLE);
                        //Take current window style and remove WS_CAPTION(title bar) from it
                        SetWindowLong(this.LegandHandle, GWL_STYLE, (style & ~WS_CAPTION));
                        style = GetWindowLong(this.LegandHandle, GWL_STYLE);
                        SetWindowLong(this.LegandHandle, GWL_STYLE, (style & ~WS_THICKFRAME));

                        // Set the legend to the max size so it fills the control.
                        MapInfo.MiPro.Interop.InteropServices.MapInfoApplication.Do(string.Format("Set Window {0} Max", this.LegendId));
                        return;
                    }
                }
            }
        }

        public IntPtr LegandHandle { get; set; }
        public int LegendId {get;set;}

        /// <summary>
        /// Gets or sets the associated mapinfo window that owns this lengend.
        /// </summary>
        public Window AssociatedWindow { get; set; }

        private void createLegendButton_Click(object sender, EventArgs e)
        {
            // Set the picture box as the new parent for the new legend.
            this.mapinfo.Do("Set Next Document Parent " + this.legandArea.Handle.ToString() + " Style 1");
            // Open the create new legend window.
            this.mapinfo.Do("Run Menu Command 816");

            string handle = this.mapinfo.Eval("WindowInfo(0,12)");
            this.LegandHandle = new IntPtr(Convert.ToInt32(handle));
        }

        private void legandArea_Resize(object sender, EventArgs e)
        {
            if (this.LegandHandle != null)
            {
                MoveWindow(this.LegandHandle, 0, 0, this.legandArea.Width, this.legandArea.Height, false);
                this.legandArea.Refresh();
            }
        }
    }
}
